<template>
  <div class="rel leftmenu hmax">
    <div class="wmax hmax bgwh leftmenu-nav">
      <div class="search">
        <el-input
          v-model="filterText"
          placeholder="按名称查询"
          clearable
          :maxlength="64"
          prefix-icon="el-icon-search"
        />
      </div>
      <div class="leftmenu-nav-tree p12 bz">
        <div class="mb10 pl5 ks-row-between">
          <div>表头字段</div>
          <el-checkbox :value="allbox" @input="changeall">全选</el-checkbox>
        </div>
        <draggable
          handle=".mover"
          :animation="200"
          :list="list"
          :delay="20"
          chosen-class="drawing-chosen"
          drag-class="drawing-drag"
          @end="handleDragEnd"
        >
          <DragTag
            :deleteDifferIds="deleteDifferIds"
            v-model="i.showColumn"
            @change="({ status, event }) => changebox(index, status, event)"
            @input="changeCheck"
            v-for="(i, index) in list"
            v-show="i.searchShow"
            :key="index + '_' + i.code"
            :item="i"
          >
            <i class="el-icon-rank mover poi" style="z-index: 1"></i>
          </DragTag>
        </draggable>
      </div>
    </div>
  </div>
</template>
<script>
import { getHmentitymodelList } from "@/apis/paas/HmEntityModelController.js"
import DragTag from "./__components__/DragTag"
import draggable from "vuedraggable"
import { differenceWith, concat } from "lodash"
export default {
  components: { draggable, DragTag },
  props: ["modelId", "columns", "isCreate", "type"],
  data() {
    return {
      filterText: "",
      list: [],
      checkedList: [],
      deleteDifferIds: [],
    }
  },
  computed: {
    allbox() {
      return this.list?.every((i) => i.showColumn)
    },
  },
  watch: {
    filterText(val) {
      if (val) {
        this.list.forEach((i) => {
          if (i.name.indexOf(val) > -1 || i.code.indexOf(val) > -1) {
            i.searchShow = true
          } else {
            i.searchShow = false
          }
        })
      } else {
        this.list.forEach((i) => {
          i.searchShow = true
        })
      }
    },
  },
  created() {
    if (!!this.isCreate) {
      this.getListData()
    } else {
      this.getListData(false)
    }
  },
  methods: {
    // 获取当前业务模型下 已发版的字段
    async getListData(show = true) {
      let list = await getHmentitymodelList({
        activated: true,
        modelId: this.modelId,
      })
      //table列 填充数据字段
      list = list.map((i) => {
        i = Object.assign(
          {
            aliasName: i.name,
            required: i.nullable ? 0 : 1,
            searchShow: true,
            showColumn: show && i.createType !== "SYSTEM", //是否显示
            columnWidth: 20, //宽度 单位字符
            precision: 2, //金额、数值 小数位
            displayRule: null, //导出设置的自定规则
            relModelCode: "", //关联主键 关联模型
            filterFields: [], //导入选择的自定义字段
            dateFormat: i.type === "DATE" ? "yyyy-MM-dd HH:mm:ss" : null, //日期格式
          },
          i
        )
        this.intConfig(i)
        return i
      })
      if (show) {
        // show===true 当前为新建模版，默认选中自定义字段
        this.list = list
      } else {
        // show===false 对比已保存数据，添加删除新增标识
        this.list = this.transformList(list, this.columns || [])
      }
      this.checkedList = this.list.filter((i) => i.showColumn)
      // 将勾选传给右侧面板
      this.$emit("changeCheck", this.checkedList)
    },

    // 初始化自定义格式
    async intConfig(formData) {
      //导入模版 自定义格式存入filterFields字段；
      //关联引用（业务模型），关联选择（业务模型）
      if (
        ["STAFF", "RELATION_SELECT", "RELATION_REFERENCE"].includes(
          formData.type
        ) &&
        !!formData.config
      ) {
        // 根据config内modelCode获取对应关联模型的字段list，初始赋值value
        try {
          let { value, modelCode } = JSON.parse(formData.config)
          if (!!value) {
            //导出模版 自定义格式存入displayRule字段，如果选中的字段有config配置，首次编辑值自动填入displayRule
            if (this.type === "EXPORT") {
              formData.displayRule =
                formData.displayRule === null ? value : formData.displayRule
            }
          }
        } catch (error) {}
      }
    },
    //移动
    handleDragEnd({ to, from, item, clone, oldIndex, newIndex }) {
      if (oldIndex !== newIndex) {
        this.checkedList = this.list.filter((i) => i.showColumn)
        this.$emit("changeCheck", this.checkedList)
      }
    },
    //接口数据发生变化
    changebox(index, status, event) {
      console.log(index, status, event)
      if (status === "delete") {
        this.list.splice(index, 1)
      } else {
        this.$nextTick(() => {
          let before_checked = this.list.filter(
            (i, idx) => i.showColumn && idx < index
          )
          let after_checked = this.list.filter(
            (i, idx) => i.showColumn && idx > index
          )
          if (event) {
            let cur = this.list.splice(index, 1)
            before_checked.push(cur[0])
            this.checkedList = before_checked.concat(after_checked)
          } else {
            this.checkedList = before_checked.concat(after_checked)
          }
          let not_checked = this.list.filter((i) => !i.showColumn)
          this.list = this.checkedList.concat(not_checked)
        })
      }
    },
    //勾选
    changeCheck(e) {
      this.checkedList = this.list.filter((i) => i.showColumn)
      this.$emit("changeCheck", this.checkedList)
    },
    //全选/反选
    changeall(v) {
      this.list = this.list.filter((i) => {
        i.showColumn = v
        return !~this.deleteDifferIds.indexOf(i.id)
      })

      this.checkedList = this.list.filter((i) => i.showColumn)
      this.$emit("changeCheck", this.checkedList)
    },

    //集合差异对比，没选的字段插入已有的字段数据里
    transformList(list, modellist) {
      //没选的
      let addDifference = differenceWith(
        list,
        modellist,
        (x, y) => x.id === y.id
      )
      //删除的
      let deleteDifference = differenceWith(
        modellist,
        list,
        (x, y) => x.id === y.id
      )
      //删除的字段id
      this.deleteDifferIds = deleteDifference.map((i) => i.id)
      let columns = modellist.map((item) => {
        let d = list.find((i) => i.id === item.id)
        if (d) {
          item = {
            ...d,
            ...item,
          }
        }
        if (this.deleteDifferIds.indexOf(item.id) > -1) {
          item = {
            ...item,
            deleteDifferIdsHas: true,
          }
        }
        return {
          ...item,
          searchShow: true,
          showColumn: true,
        }
      })
      return concat(columns, addDifference)
    },
  },
}
</script>
<style lang="scss" scoped>
.wmax {
  width: 300px;
}
.hmax {
  height: 100%;
}
.leftmenu-nav {
  box-sizing: border-box;
  padding: 4px;
  border-right: 1px solid #f1f1f1;
  z-index: 20;
  &-tree {
    height: calc(100% - 66px);
    overflow-y: auto;
  }
}
</style>
